<?php

class CuentaController extends Zend_Controller_Action
{

	public function init()
	{
		$this->em = Zend_Registry::getInstance()->entitymanager;
	}

	public function indexAction()
	{
		// action body
	}

	public function crearAction()
	{
		if (X\CheckAccess::PageAction('Cuenta.crear')) return;

		try{
			 
			// obtener los datos
			$departamentos = $this->em->createQueryBuilder()
			->select         ('d.codigoDepartamento')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('d.isDepartment')
			->addselect      ('p.codigoDepartamento as ppk')
			->addselect      ('p.nombreDepartamento as pname')
			->from           ('Default_Model_Departamento', 'd')
			->leftJoin       ('d.padre',  'p')
			->where          ('d.isDepartment = TRUE')
			->orderBy        ('d.nombreDepartamento', 'asc')
			->getQuery       ()
			->execute        ();

			$centros = $this->em->createQueryBuilder()
			->select         ('d.codigoDepartamento')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('d.isDepartment')
			->addselect      ('p.codigoDepartamento as ppk')
			->addselect      ('p.nombreDepartamento as pname')
			->from           ('Default_Model_Departamento', 'd')
			->leftJoin       ('d.padre',  'p')
			->orderBy        ('d.nombreDepartamento', 'asc')
			->getQuery       ()
			->execute        ();


			
			$Presupuestos = $this->em->createQueryBuilder()
			->select         ('p.codigoPresupuesto')
			->addselect      ('p.periodo')
			->from           ('Default_Model_Presupuesto', 'p')
			->where          ('p.periodo >= '.date('Y'))
			->orderBy        ('p.periodo', 'asc')
			->getQuery       ()
			->execute        ();


			// convertir a json
			$this->view->jsonDepartamentos = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($departamentos),
					"rows"    => $departamentos
			));
			$this->view->jsonCentros = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($centros),
					"rows"    => $centros
			));
			$this->view->jsonRubros = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($rubros),
					"rows"    => $rubros
			));
			$this->view->jsonPresupuestos = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($Presupuestos),
					"rows"    => $Presupuestos
			));
		}
		catch(Exception $e){
			$this->view->error = 'Error al cargar los datos.';

		}
	}


	public function ajaxCrearAction()
	{
		if (X\CheckAccess::PageAction('Cuenta.crear')) return;

		try{
			// obtener los parametros
			$Presupuesto = $this->_request->getPost('codigoPresupuesto');
			$Rubro = $this->_request->getPost('codigoRubro');
			$Departamento = $this->_request->getPost('codigoDepartamento');
			$CentroCostos = $this->_request->getPost('codigoCentroCostos');
			$montoInicial = $this->_request->getPost('montoInicial');

			$p=$this->em->find('Default_Model_Presupuesto', $Presupuesto);
			$r=$this->em->find('Default_Model_Rubro', $Rubro);
			$d=$this->em->find('Default_Model_Departamento', $Departamento);
			$c=$this->em->find('Default_Model_Departamento', $CentroCostos);

			$periodo=$p->getPeriodo();
			$nombreRubro=$r->getNombre();


			$cuentas = $this->em->createQueryBuilder()
			->select         ('c')
			->addselect      ('p')
			->addselect      ('r')
			->addselect      ('d')
			->from           ('Default_Model_Cuenta',  'c')
			->join           ('c.presupuesto',         'p')
			->join           ('c.rubro',               'r')
			->join           ('c.departamento',        'd')
			->join           ('c.centroCostos',        'cc')
			->where          ("r.codigoRubro=$Rubro")
			->andWhere       ("p.codigoPresupuesto=$Presupuesto")
			->andWhere       ("d.codigoDepartamento=$Departamento")
			->andWhere       ("cc.codigoDepartamento=$CentroCostos")
			->getQuery       ()
			->execute        ();

			if (count($cuentas) > 0){
				X\Msg::Failure('La cuenta ya fue creada anteriormente');
				return;
			}

			$Cuenta = new Default_Model_Cuenta;
			$Cuenta->setMontoInicial($montoInicial);
			$Cuenta->setMontoEjecutado(0);
			if($r->getEgreso()){
				$Cuenta->setMontoActual($montoInicial-0);
			}
			else{
				$Cuenta->setMontoActual(0-$montoInicial);
			}

			$Cuenta->setDepartamento($d);
			$Cuenta->setRubro($r);
			$Cuenta->setPresupuesto($p);

			//caso el centro de costos sea el departamento mismo
			$Cuenta->setCentroCostos($c);

			// guardar
			$this->em->persist($Cuenta);
			$this->em->flush();
				
			//Actualizar monto inicial del presupuesto
			//todos los montos son anuales
			if($r->getEgreso()){
				$p->setMontoInicialEgreso($p->getMontoInicialEgreso() + $montoInicial);
			}
			else{
				$p->setMontoInicialIngreso($p->getMontoInicialIngreso() + $montoInicial);
			}
				
			$this->em->persist($p);
			$this->em->flush();

			X\Msg::Success('La cuenta ha sido creada con éxito.');
		}
		catch(Exception $e){
			X\Msg::Failure('Error al crear la cuenta.'.$e->getMessage());

		}
	}
	
	public function ajaxRubrosAction(){
	
		if (X\CheckAccess::PageAction('Cuenta.crear')) return;
	
		try{
	
			$Presupuesto = $this->_request->getPost('tipo');
			
			// obtener los rubros terminales no asociados a ninguna cuenta
			// del presupuesto seleccionado
			$rubros = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('r.codigo')
			->addselect      ('r.nombreRubro')
			->addselect      ('r.general')
			->from           ('Default_Model_Rubro', 'r')
			->where          ('r.terminal= true')
			->orderBy        ('r.codigo', 'asc')
			->getQuery       ()
			->execute        ();
			
			$cuentas = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('p.codigoPresupuesto')
			->from           ('Default_Model_Cuenta', 'c')
			->leftJoin	     ('c.rubro', 'r')
			->leftJoin	     ('c.presupuesto', 'p')
			->where          ("p.codigoPresupuesto = $Presupuesto")
			->orderBy        ('r.codigoRubro', 'asc')
			->getQuery       ()
			->execute        ();
										
			
			
			
			//remoción rubros que ya están presentes en cuentas
			foreach($rubros as $key => $value){
				foreach($cuentas as $cuenta){
					if($rubros[$key]['codigoRubro'] == $cuenta['codigoRubro']){
						unset($rubros[$key]);
						break;
					}
				}
			}
			
			
			//reindexación del array rubros
			$rubros = array_values($rubros);
			
			
	
			// crear la respuesta en json
			echo Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($rubros),
					"rows"    => $rubros
			));
	
		}
	
		catch(Exception $e){
			X\Msg::Failure('Error al cargar los datos.'.$e->getMessage());
		}
	
	}
	
	public function ajaxRubrosEditarAction(){
	
		if (X\CheckAccess::PageAction('Cuenta.editar')) return;
	
		try{
	
			$Presupuesto = $this->_request->getPost('tipo');
			$codigoC = $this->_request->getPost('codigoC');
				
			
			
			//obtener la cuenta original
			$origCuenta = $this->em->find('Default_Model_Cuenta', $codigoC);
				
			// obtener los rubros terminales no asociados a ninguna cuenta
			// del presupuesto seleccionado
			$rubros = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('r.codigo')
			->addselect      ('r.nombreRubro')
			->addselect      ('r.general')
			->from           ('Default_Model_Rubro', 'r')
			->where          ('r.terminal= true')
			->orderBy        ('r.codigo', 'asc')
			->getQuery       ()
			->execute        ();
	
			$cuentas = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('p.codigoPresupuesto')
			->addselect      ('c.codigoCuenta')
			->from           ('Default_Model_Cuenta', 'c')
			->leftJoin	     ('c.rubro', 'r')
			->leftJoin	     ('c.presupuesto', 'p')
			->where          ("p.codigoPresupuesto = $Presupuesto")
			->andWhere       ("c.codigoCuenta <> $codigoC")
			->orderBy        ('r.codigoRubro', 'asc')
			->getQuery       ()
			->execute        ();
	
			
				
			
			if($Presupuesto != $origCuenta->getPresupuesto()->getCodigoPresupuesto()){
				//remoción rubros que ya están presentes en cuentas
				foreach($rubros as $key => $value){
					foreach($cuentas as $cuenta){
						if($rubros[$key]['codigoRubro'] == $cuenta['codigoRubro']){
							unset($rubros[$key]);
							break;
						}
					}
				}
			}
			else{
				//remoción rubros que ya están presentes en cuentas
				foreach($rubros as $key => $value){
					foreach($cuentas as $cuenta){
						if($rubros[$key]['codigoRubro'] == $cuenta['codigoRubro']
								&& $cuenta['codigoCuenta'] != $codigoC){
							unset($rubros[$key]);
							break;
						}
					}
				}
				
			}
			
				
			//reindexación del array rubros
			$rubros = array_values($rubros);
				
			
	
			// crear la respuesta en json
			echo Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($rubros),
					"rows"    => $rubros
			));
	
		}
	
		catch(Exception $e){
			X\Msg::Failure('Error al cargar los datos.'.$e->getMessage());
		}
	
	}


	public function listarAction()
	{
		if (X\CheckAccess::PageAction('Cuenta.listar')) return;

		try{
			// obtener los datos
			 
			$cuentas = $this->em->createQueryBuilder()
			->select         ('c.codigoCuenta')
			->addselect      ('c.montoInicial')
			->addselect      ('c.montoActual')
			->addselect      ('c.montoEjecutado')
			->addselect      ('p.periodo')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('cc.nombreDepartamento as nombreCentro')
			->addselect      ('r.nombreRubro')
			->addselect      ('r.codigo')
			->from           ('Default_Model_Cuenta', 'c')
			->join           ('c.presupuesto',   'p')
			->leftJoin       ('c.departamento',  'd')
			->leftJoin 	     ('c.centroCostos', 'cc')
			->join           ('c.rubro',        'r')
			->orderBy        ('c.codigoCuenta', 'asc')
			->setFirstResult (0)
			->setMaxResults  (20)
			->getQuery       ()
			->execute        ();

			$cantidad = $this->em->createQueryBuilder()
			->select   ('count(c.codigoCuenta)')
			->from     ('Default_Model_Cuenta', 'c')
			->getQuery ()
			->getSingleScalarResult();
			 

			// convertir a json
			$this->view->jsondata = Zend_Json::encode(Array(
					"success" => true,
					"total"   => $cantidad,
					"rows"    => $cuentas
			));
		}
		catch(Exception $e){
			$this->view->error = 'Error al cargar las cuentas.';
		}
	}


	public function ajaxListarAction()
	{
		if (X\CheckAccess::PageAction('Cuenta.listar')) return;

		try{

			// obtener los parametros
			$start = $this->_request->getPost("start");
			$limit = $this->_request->getPost("limit");
			$sort  = $this->_request->getPost("sort");
			$dir   = $this->_request->getPost("dir");
				
			if($sort == 'codigoNombre') $sort='codigo';

			// parametros por defecto
			$sort = isset($sort)? $sort : 'codigoCuenta';
			$dir  = isset($dir)?  $dir  : 'asc';



			// prefijo para el sort
			$prefijo = ($sort == 'nombreRubro'?        'r.' :
					($sort == 'nombreDepartamento'? 'd.' :
							($sort == 'periodo'?			   'p.' :
		       ($sort == 'codigo'?'r.':'c.') )));

			$cuentas = $this->em->createQueryBuilder()
			->select         ('c.codigoCuenta')
			->addselect      ('c.montoInicial')
			->addselect      ('c.montoActual')
			->addselect      ('c.montoEjecutado')
			->addselect      ('p.periodo')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('cc.nombreDepartamento as nombreCentro')
			->addselect      ('r.nombreRubro')
			->addselect      ('r.codigo')
			->from           ('Default_Model_Cuenta', 'c')
			->join           ('c.presupuesto',   'p')
			->leftjoin       ('c.departamento',  'd')
			->leftJoin       ('c.centroCostos', 'cc')
			->join           ('c.rubro',        'r')
			->orderBy        ($prefijo.$sort, $dir)
			->setFirstResult ($start)
			->setMaxResults  ($limit)
			->getQuery       ()
			->execute        ();

			$cantidad = $this->em->createQueryBuilder()
			->select   ('count(c.codigoCuenta)')
			->from     ('Default_Model_Cuenta', 'c')
			->getQuery ()
			->getSingleScalarResult();

			// convertir a json
			echo Zend_Json::encode(Array(
					"success" => true,
					"total"   => $cantidad,
					"rows"    => $cuentas
			));
		}
		catch(Exception $e){
			$this->view->error = 'Error al cargar los usuarios.';
		}

	}



	public function editarAction()
	{

		if (X\CheckAccess::PageAction('Cuenta.editar')) return;

		try{
			// obtener los parametros
			$id = $this->_request->getQuery('id');

			// obtener los datos
			$origCuenta = $this->em->find('Default_Model_Cuenta', $id);
			
			$this->view->cuenta = $origCuenta;
			
			// obtener el codigo del presupuesto de la cuenta
			$Presupuesto = $origCuenta->getPresupuesto()->getCodigoPresupuesto();
			
			

			// obtener los datos
			$departamentos = $this->em->createQueryBuilder()
			->select         ('d.codigoDepartamento')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('d.isDepartment')
			->addselect      ('p.codigoDepartamento as ppk')
			->addselect      ('p.nombreDepartamento as pname')
			->from           ('Default_Model_Departamento', 'd')
			->leftJoin       ('d.padre',  'p')
			->where          ('d.isDepartment = TRUE')
			->orderBy        ('d.nombreDepartamento', 'asc')
			->getQuery       ()
			->execute        ();

			$centros = $this->em->createQueryBuilder()
			->select         ('d.codigoDepartamento')
			->addselect      ('d.nombreDepartamento')
			->addselect      ('d.isDepartment')
			->addselect      ('p.codigoDepartamento as ppk')
			->addselect      ('p.nombreDepartamento as pname')
			->from           ('Default_Model_Departamento', 'd')
			->leftJoin       ('d.padre',  'p')
			->orderBy        ('d.nombreDepartamento', 'asc')
			->getQuery       ()
			->execute        ();

			$rubros = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('r.nombreRubro')
			->addselect      ('r.codigo')
			->addselect      ('r.general')
			->from           ('Default_Model_Rubro', 'r')
			->where          ('r.terminal= true')
			->orderBy        ('r.codigo', 'asc')
			->getQuery       ()
			->execute        ();
			
			
			$cuentas = $this->em->createQueryBuilder()
			->select         ('r.codigoRubro')
			->addselect      ('p.codigoPresupuesto')
			->from           ('Default_Model_Cuenta', 'c')
			->leftJoin	     ('c.rubro', 'r')
			->leftJoin	     ('c.presupuesto', 'p')
			->where          ("p.codigoPresupuesto = $Presupuesto")
			->andWhere       ("c.codigoCuenta <> $id")
			->orderBy        ('r.codigoRubro', 'asc')
			->getQuery       ()
			->execute        ();
				
			
			//remoción rubros que ya están presentes en cuentas
			foreach($rubros as $key => $value){
				foreach($cuentas as $cuenta){
					if($rubros[$key]['codigoRubro'] == $cuenta['codigoRubro']
							&& $cuenta['codigoCuenta'] != $id){
						unset($rubros[$key]);
						break;
					}
				}
			}
			
			
				
			//reindexación del array rubros
			$rubros = array_values($rubros);

			$Presupuestos = $this->em->createQueryBuilder()
			->select         ('p.codigoPresupuesto')
			->addselect      ('p.periodo')
			->from           ('Default_Model_Presupuesto', 'p')
			->where          ('p.periodo >= '.date('Y'))
			->orderBy        ('p.periodo', 'asc')
			->getQuery       ()
			->execute        ();

			// convertir a json
			$this->view->jsonDepartamentos = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($departamentos),
					"rows"    => $departamentos
			));
			$this->view->jsonCentros = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($centros),
					"rows"    => $centros
			));
			$this->view->jsonRubros = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($rubros),
					"rows"    => $rubros
			));
			$this->view->jsonPresupuestos = Zend_Json::encode(Array(
					"success" => true,
					"total"   => count($Presupuestos),
					"rows"    => $Presupuestos
			));

		}

		catch(Exception $e){
			$this->view->error = 'Error al cargar datos.';
		}

	}


	public function ajaxEliminarAction()
	{
		try{
			// obtener los parametros
			$id = $this->_request->getPost('id');
			$movimientos=$this->em->createQueryBuilder()
			->select    ('c.codigoMovimiento')
			->addselect ('p.codigoCuenta')
			->from      ('Default_Model_Movimiento','c')
			->join      ('c.cuenta',   'p')
			->where     ("p.codigoCuenta=$id")
			->getQuery       ()
			->execute        ();
			if(count($movimientos)){
				X\Msg::Failure('No se puede eliminar la cuenta existen movimientos dependientes de esta cuenta');
				return;
			};
			// obtener el objeto
			$cuenta = $this->em->find('Default_Model_Cuenta', $id);
			 
			$p =  $cuenta->getPresupuesto();
			$r =  $cuenta->getRubro();

			//Actualizar monto inicial del presupuesto
			if($r->getEgreso()){
				$p->setMontoInicialEgreso($p->getMontoInicialEgreso() - $cuenta->getMontoInicial());
			}
			else{
				$p->setMontoInicialIngreso($p->getMontoInicialIngreso() - $cuenta->getMontoInicial());
			}


			$this->em->remove($cuenta);
			$this->em->flush();

			X\Msg::Success('La cuenta se ha eliminado con exito.');
		}
		catch(Exception $e){
			X\Msg::Failure('Error al eliminar la cuenta.'.$e->getMessage());
		}
	}



	public function ajaxEditarAction()
	{

		if (X\CheckAccess::PageAction('Cuenta.editar')) return;

		try{
			// obtener los parametros
			$cod     = $this->_request->getPost('codigoCuenta');
			$Presupuesto = $this->_request->getPost('codigoPresupuesto');
			$Rubro = $this->_request->getPost('codigoRubro');
			$Departamento = $this->_request->getPost('codigoDepartamento');
			$CentroCostos = $this->_request->getPost('codigoCentroCostos');
			$montoInicial = $this->_request->getPost('montoInicial');

			$p=$this->em->find('Default_Model_Presupuesto', $Presupuesto);
			$r=$this->em->find('Default_Model_Rubro', $Rubro);
			$d=$this->em->find('Default_Model_Departamento', $Departamento);
			$c=$this->em->find('Default_Model_Departamento', $CentroCostos);

			//obtener cuenta con sus datos antes de editar
			$Cuenta= $this->em->find('Default_Model_Cuenta',$cod);
			
			//obtener el presupuesto anterior de la cuenta
			$oldP = $this->em->find('Default_Model_Presupuesto', $Cuenta->getPresupuesto()->getCodigoPresupuesto());

			//verificar si hubieron cambios en presupuesto, rubro, departamento y/o centro de costos
			$cambios =  $Presupuesto != $oldP->getCodigoPresupuesto() ||
			$Rubro != $Cuenta->getRubro()->getCodigoRubro() ||
			$Departamento != $Cuenta->getDepartamento()->getCodigoDepartamento() ||
			$CentroCostos != $Cuenta->getCentroCostos()->getCodigoDepartamento();

			$cuentas = $this->em->createQueryBuilder()
			->select         ('c')
			->addselect      ('p')
			->addselect      ('r')
			->addselect      ('d')
			->from           ('Default_Model_Cuenta',  'c')
			->join           ('c.presupuesto',         'p')
			->join           ('c.rubro',               'r')
			->join           ('c.departamento',        'd')
			->join           ('c.centroCostos',        'cc')
			->where          ("r.codigoRubro=$Rubro")
			->andWhere       ("p.codigoPresupuesto=$Presupuesto")
			->andWhere       ("d.codigoDepartamento=$Departamento")
			->andWhere       ("cc.codigoDepartamento=$CentroCostos")
			->getQuery       ()
			->execute        ();

			//Verificar si ya existe la cuenta (si se cambio un ppto, dpto, centro de costos o rubro)
			//Se acepta el caso que sólamente se haya cambiado el monto inicial
			if (count($cuentas) > 0 && $cambios){
				X\Msg::Failure('La cuenta ya fue creada anteriormente');
				return;
			}

			//si ya existen movimientos relacionados a la cuenta, no permitir ningún cambio
			if($Cuenta->getMovimientos()->count()>0 && $cambios){
				X\Msg::Failure('La cuenta ya ha sido utilizada en algun movimiento.');
				return;
			}

			//asignar departamento y centro de costos
			if($p->getCodigoPresupuesto() != $oldP->getCodigoPresupuesto())
				$Cuenta->setPresupuesto($p);
			$Cuenta->setDepartamento($d);
			$Cuenta->setCentroCostos($c);

				
			$montoInicialAnteriorCuenta =  $Cuenta->getMontoInicial();
			$montoEjecutado = $Cuenta->getMontoEjectuado();

			$Cuenta->setMontoInicial($montoInicial);
			if($r->getEgreso()){
				$Cuenta->setMontoActual($montoInicial-$montoEjecutado);
			}
			else{
				$Cuenta->setMontoActual($montoEjecutado-$montoInicial);
			}

			// guardar
			$this->em->persist($Cuenta);
			$this->em->flush();
				
			//Actualizar monto inicial del presupuesto
			if($r->getEgreso()){
				$montoEgresoPresupuesto = $p->getMontoInicialEgreso() - $montoInicialAnteriorCuenta;
				$p->setMontoInicialEgreso($montoEgresoPresupuesto + $montoInicial);
				$oldP->setMontoInicialEgreso($montoEgresoPresupuesto - $montoInicial);
			}
			else{
				$montoIngresoPresupuesto = $p->getMontoInicialIngreso() - $montoInicialAnteriorCuenta;
				$p->setMontoInicialIngreso($montoIngresoPresupuesto + $montoInicial);
				$oldP->setMontoInicialIngreso($montoIngresoPresupuesto - $montoInicial);
			}
				
			$this->em->persist($p);
			$this->em->flush();

			X\Msg::Success('La cuenta ha sido modificada con éxito.');
		}
		catch(Exception $e){
			X\Msg::Failure('Error al guardar la cuenta.'.$e->getMessage());

		}

	}

}


